/*
 * Copyright (c) 2010, kamaboco <kamaboco@gmail.com>.
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * 
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 
 * 3. This notice may not be removed or altered from any source
 * distribution.
 */

#define D_PORTING 1

#include "dnkf.h"
#include "dnkf_internal.h"

#include "utf8tbl.c"
#include "nkf.c"

#include <locale.h>

int std_getc(FILE *f)
{
    if (!nkf_buf_empty_p(nkf_state->std_gc_buf))
    {
        return nkf_buf_pop(nkf_state->std_gc_buf);
    }
    else
    {
    	return dnkf_internal_getc();
    }
}

void std_putc(nkf_char c)
{
    dnkf_internal_putc(c);
}


void reinit_dnkf(void)
{
    dnkf_internal_input_clear();
    dnkf_internal_output_clear();
}


D_immutable D_string dnkf_version(){
    D_string ret;
    
    ret.length = strlen(NKF_VERSION);
    ret.ptr = NKF_VERSION;
    
    return ret;
}


void options0(void)
{
    const unsigned char *optStr;
    
    reinit();
    
    optStr = (const unsigned char *)dnkf_get_option().ptr;
    
    if ( optStr != NULL )
    {
        options(optStr);
    }
}


D_immutable D_string dnkf_convert(D_immutable D_char *optStr, 
                                  D_size_t optLen, 
                                  const void *inStr, 
                                  D_size_t inLen)
{
    D_string ret = {0, NULL};
    
    if (inLen > 0)
    {
        dnkf_set_option(optStr, optLen);
        options0();
        dnkf_internal_output_clear();
        dnkf_internal_input_set_buffer(inStr, inLen);
        
	kanji_convert(NULL);
        
        ret = dnkf_internal_output_get();
        dnkf_internal_output_clear();
        dnkf_internal_input_clear();
    }
    
    return ret;
}


D_immutable D_string dnkf_guess(const void *inStr, 
                                D_size_t inLen)
{
    int prev_guess_f;
    int prev_nop_f;
    
    dnkf_set_option(NULL, 0);
    options0();
    
    prev_guess_f = guess_f;
    prev_nop_f = nop_f;
    
    dnkf_internal_input_set_buffer(inStr, inLen);
    dnkf_internal_output_clear();
    
    guess_f = 1;
    nop_f = 2;
    
    kanji_convert(NULL);
    
    guess_f = prev_guess_f;
    nop_f = prev_nop_f;
    
    dnkf_internal_input_clear();
    dnkf_internal_output_clear();
    
    {
        const char *guessed_code;
        
        guessed_code = get_guessed_code();
        
        D_string ret = {0, ""};
        
        if (guessed_code)
        {
            ret.ptr = (char *)guessed_code;
            ret.length = strlen(guessed_code);
        }
        
        return ret;
    }
}


void dnkf_module_ctor(void)
{
#ifdef DEFAULT_CODE_LOCALE
    setlocale(LC_CTYPE, "");
#endif
}


void dnkf_module_dtor(void)
{
}

